/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package phd.changeidentifiers.testing.display.objects;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;
import phd.changeidentifiers.testing.display.database.DataSourceNotInitialisedException;
import phd.changeidentifiers.testing.display.database.DatabaseConnection;
import phd.dupenois.changeidentifiers.dotpatterns.Dot;
import phd.dupenois.changeidentifiers.dotpatterns.DotPattern;
import phd.dupenois.changeidentifiers.footprints.Footprint;
import uk.co.dupenois.geometry.Coordinate;

/**
 *
 * @author Max
 */
public class TestRetrievalEngine {
    public static TestDBObject[] getTests() throws SQLException, DataSourceNotInitialisedException{
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try{
            connection = DatabaseConnection.getConnection();
            statement = connection.prepareStatement("SELECT * FROM `ci-tests`");
            resultSet = statement.executeQuery();
            Vector<TestDBObject> tests = new Vector<TestDBObject>();
            TestDBObject test;
            while(resultSet.next()){
                test = new TestDBObject();
                test.setStart(resultSet.getLong("start"));
                test.setStartWithoutChangeIdentifiers(resultSet.getLong("start-without-change-identifiers"));
                test.setTimeTaken(resultSet.getLong("time-taken"));
                test.setTimeTakenWithoutChangeIdentifiers(resultSet.getLong("time-taken-without-change-identifiers"));
                test.setFootprintAlgorithmClass(resultSet.getString("footprint-algorithm"));
                test.setTitle(resultSet.getString("title"));
                test.setDescription(resultSet.getString("description"));
                test.setId(resultSet.getInt("id"));
                tests.add(test);
            }
            return tests.toArray(new TestDBObject[tests.size()]);
        }finally{
            DatabaseConnection.closeResultSet(resultSet);
            DatabaseConnection.closeStatement(statement);
            DatabaseConnection.closeConnection(connection);
        }
    }
    public static void fillTest(TestDBObject test) throws SQLException, DataSourceNotInitialisedException{
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try{
            connection = DatabaseConnection.getConnection();
            statement = connection.prepareStatement("SELECT * FROM `ci-change-identifier-sets_tests` WHERE `test-id` = ?");
            statement.setInt(1, test.getId());
            resultSet = statement.executeQuery();
            int ciset_id = -1;
            if(resultSet.next()) ciset_id = resultSet.getInt("set-id");
            ChangeIdentifierSetDBObject ciset = null;
            if(ciset_id > -1){
                statement = connection.prepareStatement("SELECT * FROM `ci-change-identifier-sets` WHERE `id` = ?");
                statement.setInt(1, ciset_id);
                resultSet = statement.executeQuery();
                if(resultSet.next()){
                    ciset = new ChangeIdentifierSetDBObject();
                    ciset.setName(resultSet.getString("name"));
                    ciset.setVersion(resultSet.getString("version"));
                    ciset.setDescription(resultSet.getString("description"));
                    ciset.setMaxFails(resultSet.getInt("max-fails"));
                    ciset.setTotalThreshold(resultSet.getDouble("total-threshold"));
                }
            }
            test.setChangeIdentifierSet(ciset);
            statement = connection.prepareStatement("SELECT * FROM `ci-time-steps` WHERE `test-id` = ?");
            statement.setInt(1, test.getId());
            resultSet = statement.executeQuery();
            Vector<TimeStepDBObject> timeSteps = new Vector<TimeStepDBObject>();
            Vector<TimeStepDBObject> timeStepsWithoutChangeIdentifiers = new Vector<TimeStepDBObject>();
            TimeStepDBObject timeStep;
            boolean hasChangeIdentifiers;
            while(resultSet.next()){
                timeStep = new TimeStepDBObject();
                timeStep.setId(resultSet.getInt("id"));
                timeStep.setStarted(resultSet.getLong("start"));
                timeStep.setTimeTaken(resultSet.getLong("time-taken"));
                timeStep.setAlgStarted(resultSet.getLong("algorithm-start"));
                timeStep.setAlgTimeTaken(resultSet.getLong("algorithm-time-taken"));
                timeStep.setRedraw(resultSet.getBoolean("redrew"));
                hasChangeIdentifiers = resultSet.getBoolean("has-change-identifiers");
                timeStep.setSymmetricAreaDifference(resultSet.getDouble("symmetric-area-difference"));
                if(hasChangeIdentifiers){
                    timeSteps.add(timeStep);
                }else{
                    timeStepsWithoutChangeIdentifiers.add(timeStep);
                }
            }
//            System.out.println("Time steps "+timeSteps.size());
            statement = connection.prepareStatement("SELECT * FROM `ci-footprints` WHERE `step-id` = ?");
            for(TimeStepDBObject step : timeSteps){
                statement.setInt(1, step.getId());
                resultSet = statement.executeQuery();
                if(resultSet.next()){
                    step.setFootprint(convertStringToFootprint(resultSet.getString("footprint")));
                }
            }
            for(TimeStepDBObject step : timeStepsWithoutChangeIdentifiers){
                statement.setInt(1, step.getId());
                resultSet = statement.executeQuery();
                if(resultSet.next()){
                    step.setFootprint(convertStringToFootprint(resultSet.getString("footprint")));
                }
            }
            statement = connection.prepareStatement("SELECT * FROM `ci-dot-patterns` WHERE `step-id` = ?");
            for(TimeStepDBObject step : timeSteps){
                statement.setInt(1, step.getId());
                resultSet = statement.executeQuery();
                if(resultSet.next()){
                    step.setDotPattern(convertStringToDotPattern(resultSet.getString("pattern")));
                }
            }
            for(TimeStepDBObject step : timeStepsWithoutChangeIdentifiers){
                statement.setInt(1, step.getId());
                resultSet = statement.executeQuery();
                if(resultSet.next()){
                    step.setDotPattern(convertStringToDotPattern(resultSet.getString("pattern")));
                }
            }
            for(TimeStepDBObject step : timeSteps) test.addTimeStep(step);
            for(TimeStepDBObject step : timeStepsWithoutChangeIdentifiers) test.addTimeStepWithoutChangeIdentifiers(step);
        }finally{
            DatabaseConnection.closeResultSet(resultSet);
            DatabaseConnection.closeStatement(statement);
            DatabaseConnection.closeConnection(connection);
        }
    }
    private static DotPattern convertStringToDotPattern(String string){
        String[] linesStr = string.split("[\\n\\r]");
        Dot dot;
        double x;
        double y;
        DotPattern dotPattern = new DotPattern();
        String[] values;
        for(String lineStr : linesStr){
            values = lineStr.split(",");
            if(values.length<2) continue;
            try {
                x = Double.parseDouble(values[0].trim());
                y = Double.parseDouble(values[1].trim());
                dot = new Dot(x, y);
                dotPattern.addDot(dot);
            } catch (NumberFormatException numberFormatException) {
                continue;
            }
        }
        return dotPattern;
    }
    private static Footprint convertStringToFootprint(String string){
        String[] linesStr = string.split("[\\n\\r]");
        Coordinate start;
        Coordinate finish;
        double x;
        double y;
        Footprint footprint = new Footprint();
        String[] values;
        for(String lineStr : linesStr){
            values = lineStr.split(",");
            if(values.length<4) continue;
            try {
                x = Double.parseDouble(values[0].trim());
                y = Double.parseDouble(values[1].trim());
                start = new Coordinate(x, y);
                x = Double.parseDouble(values[2].trim());
                y = Double.parseDouble(values[3].trim());
                finish = new Coordinate(x, y);
                footprint.addLine(start, finish);
            } catch (NumberFormatException numberFormatException) {
                continue;
            }
        }
        return footprint;
    }
}
